import { _decorator, Component, EventTouch, Input, input, instantiate, IVec2, Node, tween, Tween, UITransform, Vec2, Vec3 } from 'cc'
import DataManager from '../../Global/DataManager'
import { EntityTypeEnum, IActor, IBullet, InputTypeEnum } from '../../Common'
import { EntityManager } from '../../Base/EntityManager'
import { EntityStateEnum, EventEnum } from '../../Enum'
import { WeaponManager } from '../Weapon/WeaponManager'
import { rad2Angle } from '../../Utils'
import { BulletStateMachine } from './BulletStateMachine'
import EventManager from '../../Global/EventManager'
import { ExplosionManager } from '../Explosion/ExplosionManager'
import ObjectPoolManager from '../../Global/ObjectPoolManager'
const { ccclass, property } = _decorator

@ccclass('BulletManager')
export class BulletManager extends EntityManager {

    type: EntityTypeEnum
    id: number
    private targetPos: Vec3
    private tw: Tween<any>

    init(data: IBullet) {
        this.id = data.id
        this.type = data.type
        this.fsm = this.addComponent(BulletStateMachine)
        this.fsm.init(data.type)

        this.state = EntityStateEnum.Idle
        this.node.active = false // 一开始子弹的坐标是初始的武器 point 坐标

        EventManager.Instance.on(EventEnum.ExplosionBorn, this.handleExplosionBorn, this)
    }

    handleExplosionBorn(id: number, { x, y }: IVec2) {
        if (id !== this.id) {
            return
        }

        // const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Explosion)
        // const explosion = instantiate(prefab)
        // explosion.setParent(DataManager.Instance.stage)
        const explosion = ObjectPoolManager.Instance.get(EntityTypeEnum.Explosion)
        // 从对象池取出的可能已经有 ExplosionManager 组件了
        const em = explosion.getComponent(ExplosionManager) || explosion.addComponent(ExplosionManager)
        em.init(EntityTypeEnum.Explosion, { x, y })

        EventManager.Instance.off(EventEnum.ExplosionBorn, this.handleExplosionBorn, this)
        DataManager.Instance.bulletMap.delete(id)
        // this.node.destroy()
        ObjectPoolManager.Instance.ret(this.node)
    }

    render(data: IBullet) {
        this.node.active = true // 确保子弹节点是激活的，up的代码里没写，游戏子弹部分会消失
        this.renderPos(data)
        this.renderDire(data)
    }

    renderPos(data: IBullet) {
        const { direction, position } = data
        const newPos = new Vec3(position.x, position.y)
        if (!this.targetPos) { // 第一次渲染位置
            this.node.active = true
            this.node.setPosition(newPos)
            this.targetPos = new Vec3(newPos)
        } else if (!this.targetPos.equals(newPos)) { // 位置发生变化才真正执行，因为数据每100毫秒才发一次，但是render是每帧
            this.tw?.stop() // 停止之前的动画
            this.node.setPosition(this.targetPos)
            this.targetPos.set(newPos)
            this.tw = tween(this.node).to(0.1, {
                position: this.targetPos,
            }).start()
        }
    }

    renderDire(data: IBullet) {
        const { direction, position } = data

        const side = Math.sqrt(direction.x ** 2 + direction.y ** 2)
        let angle
        if (direction.x > 0) {
            angle = rad2Angle(Math.asin(direction.y / side))
        } else {
            // 朝左侧发射子弹的时候，子弹朝向要处理一下
            angle = rad2Angle(Math.asin(-direction.y / side)) + 180
        }

        this.node.setRotationFromEuler(0, 0, angle)
    }
}
